package com.oreilly.ez.util;

import com.oreilly.ez.base.ExcelColumnAdaptor;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class ExcelUtil {

    @Autowired
    private Map<String, ExcelColumnAdaptor> adaptors;

    private static Map<String, Integer> map = new HashMap();

    static {

        for (int i = 1; i <= 26; i++) {
            map.put(String.valueOf((char) (96 + i)).toUpperCase(), i - 1);
        }
//        map.put("A", 0);
//        map.put("B", 1);

    }

    public static  void createSheet(HSSFWorkbook workbook, String sheetName, List<?> dataList) throws Exception {


        HSSFSheet sheet = workbook.createSheet(sheetName);
        if (dataList == null || dataList.size() == 0) {
            return;
        }

        Object object = dataList.get(0);
        setHead(object, sheet);

        for (int i = 0; i < dataList.size(); i++) {

            Object t = dataList.get(i);
            HSSFRow row = sheet.createRow(i + 1);
            setOneRow(row, t);
        }


    }

    private static <T> void setOneRow(HSSFRow row, T t) throws IllegalAccessException, InstantiationException {
        Field[] fields = t.getClass().getDeclaredFields();

//        for (int j = 0; j < fields.length; j++) {
//
//            Field field = fields[j];
//            field.setAccessible(true);
//            HSSFCell cell = row.createCell(j);
//            cell.setCellType(CellType.STRING);
//            cell.setCellValue(field.get(t) == null ? "" : String.valueOf(field.get(t)));
//
//        }

        for (Field field : fields) {
            field.setAccessible(true);

            ExcelAnnotation annotation = field.getAnnotation(ExcelAnnotation.class);
            if (annotation != null) {

                String column = annotation.column();
                HSSFCell cell = createCell(row, column);
                cell.setCellType(CellType.STRING);
                Object val = field.get(t);
                if(val == null){
                    cell.setCellValue("");
                }

                Class<? extends ExcelColumnAdaptor> adaptor = annotation.adaptor();
//                String simpleName = adaptor.getSimpleName();
//                System.out.println("simpleName = " + simpleName);
                ExcelColumnAdaptor excelColumnAdaptor = adaptor.newInstance();

                String strVal = excelColumnAdaptor.val(val);
                cell.setCellValue(strVal);
            }

        }
    }

    private static  void setHead(Object t, HSSFSheet sheet) {
        HSSFRow head = sheet.createRow(0);


        Field[] fields = t.getClass().getDeclaredFields();


        for (Field field: fields) {

//            Field field = fields[i];
            field.setAccessible(true);
            String name = field.getName();
            ExcelAnnotation annotation = field.getAnnotation(ExcelAnnotation.class);
            if (annotation != null) {
                String zhName = annotation.zhName();
                if (zhName != null && zhName.length() > 0) {


                    name = zhName;
//                    HSSFCell cell = head.createCell(i);
                    String column = annotation.column();
                    HSSFCell cell = createCell(head, column);
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(name);
                }
            }


        }
    }

    private static HSSFCell createCell(HSSFRow row, String column) {

        if(column == null || column.length() == 0){
            throw new RuntimeException("column is required in annotation");
        }
        Integer col = map.get(column);
        return row.createCell(col);
    }
}
